package com.mobile.paperazi;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.RectF;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;

import com.mobile.paperazi.data.Constants;
import com.mobile.paperazi.data.Content;
import com.mobile.paperazi.data.Page;
import com.mobile.paperazi.data.Tag;
import com.mobile.paperazi.view.CustomView;
import com.mobile.paperazi.view.ResizableImageView;

public class PaperaziActivity extends Activity implements OnClickListener {

	Bitmap mIcon_val;
	CustomView view;
	private Button btn;
	JSONArray array = null;
	RelativeLayout ly;
	ResizableImageView img;
	ProgressBar bar; 
	FrameLayout layout;
	Page page;
	String url;
	String urlString;

	private GestureDetector mGestureDetector;
	private OnTouchListener mGestureListener;
	private boolean mIsScrolling = false;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
		if(!isNetworkAvailable()){
			showDialog(3);
		}
		Intent intent = getIntent();
		urlString = (String)intent.getExtras().get(Constants.URL);
		try {
			URL papUrl = new URL(urlString);
			if(!papUrl.getHost().contains(Constants.PAPERAZI)){
				Intent in = new Intent(this, WebActivity.class);
				Content content = new Content();
				content.setUrl(urlString);
				in.putExtra(Constants.CONTENT, content);
				in.putExtra(Constants.IS_PAPERAZI, false);
				startActivity(in);
				finish();
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		
		Uri uri = Uri.parse(urlString);
		String param = uri.getQueryParameter(Constants.AR_PAGE_ID);
		if(param == null){
			showDialog(2);
		}
		else{
			url = Constants.JSON_URL.concat(param);
			LayoutInflater lf = getLayoutInflater();
			layout = (FrameLayout)lf.inflate(R.layout.activity_paperazi, null);
			setContentView(layout);
			ly = (RelativeLayout)layout.findViewById(R.id.loadView);
			img = (ResizableImageView)layout.findViewById(R.id.imgPaper);
			bar = (ProgressBar)layout.findViewById(R.id.progressBar1);
			initGestureDetection();
			LoadDataAsyncTask task = new LoadDataAsyncTask();
			task.execute();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.paperazi, menu);
		return true;
	}

	@Override
	public void onClick(View v) {
		if(v.getId() == btn.getId()){
			Intent in = new Intent(this, OptionPopupActivity.class);
			startActivity(in);
		}
		
	}
	
	
	private boolean isNetworkAvailable() {
		boolean status = false;
		try {
			ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
			NetworkInfo netInfo = cm.getNetworkInfo(0);
			if (netInfo != null
					&& netInfo.getState() == NetworkInfo.State.CONNECTED) {
				status = true;
			} else {
				netInfo = cm.getNetworkInfo(1);
				if (netInfo != null
						&& netInfo.getState() == NetworkInfo.State.CONNECTED)
					status = true;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return status;
	}

	public void initGestureDetection() {
		// Gesture detection
		mGestureDetector = new GestureDetector(new SimpleOnGestureListener() {
			@Override
			public boolean onDoubleTap(MotionEvent e) {
				return true;
			}

			@Override
			public boolean onSingleTapConfirmed(MotionEvent e) {
				handlePopup(e);
				return true;
			}

			@Override
			public boolean onScroll(MotionEvent e1, MotionEvent e2,
					float distanceX, float distanceY) {
				mIsScrolling = true;
				return true;
			}
			
			@Override
			/**
			 * Don't know why but we need to intercept this guy and return true so that the other gestures are handled.
			 * https://code.google.com/p/android/issues/detail?id=8233
			 */
			public boolean onDown(MotionEvent e) {
				return true;
			}
		});

		mGestureListener = new View.OnTouchListener() {
			public boolean onTouch(View v, MotionEvent event) {

				if (mGestureDetector.onTouchEvent(event)) {
					return true;
				}

				if (event.getAction() == MotionEvent.ACTION_UP) {
					if (mIsScrolling) {
						mIsScrolling = false;
					}
					;
				}

				return false;
			}
		};

		img.setOnTouchListener(mGestureListener);
	}
	
	@Override
	public void onBackPressed() {
		super.onBackPressed();
		Intent intent = new Intent(this, MainActivity.class);
		startActivity(intent);
		this.finish();
		
	}
	
	private void handlePopup(MotionEvent e){
		float height = img.getHeight();
		float width = img.getWidth();
		float x = e.getX()*img.getDrawable().getIntrinsicWidth()/width;
		float y = e.getY()*img.getDrawable().getIntrinsicHeight()/height;
		float a = e.getRawX();
		float b = e.getRawY();
		
		if(view != null){
			HashMap<RectF, List<Content>> map = view.getContentMap();
			Set<RectF> set = map.keySet();
			for (RectF rectF : set) {
				if(((rectF.left <= x) && ( x <= rectF.right)) && ((rectF.top <= y) && ( y <=rectF.bottom))){
					Intent intent = new Intent();
					if(map.get(rectF).size() > 1) {
						intent.setClass(this, OptionPopupActivity.class);
						intent.putParcelableArrayListExtra(Constants.CONTENT, (ArrayList<Content>) map.get(rectF));
						startActivity(intent);
					}
					else if(map.get(rectF).size() == 1){
						intent.setClass(this, WebActivity.class);
						intent.putExtra(Constants.CONTENT, (Content)map.get(rectF).get(0));
						intent.putExtra(Constants.IS_PAPERAZI, true);
						startActivity(intent);
					}
					else{
						
					}
					break;
				}
				
			}
		}
	}
	
	private class LoadDataAsyncTask extends AsyncTask<Void, Integer, Void>{

		int progress = 0;
		@Override
		protected Void doInBackground(Void... params) {
			init();
			while (mIcon_val == null) {
				if(progress == 5){
					break;
				}
				SystemClock.sleep(5000);
				bar.setProgress(progress);
				progress++;
				
			}
			return null;
		}
		
		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			ly.setVisibility(View.INVISIBLE);
			img.setVisibility(View.VISIBLE);
			if(mIcon_val == null){
				showDialog(1);
			}
			else{
				Bitmap mutableBitmap = mIcon_val.copy(Bitmap.Config.ARGB_8888, true);
				Canvas canvas = new Canvas(mutableBitmap);
				view = new CustomView(PaperaziActivity.this, page);				
				view.draw(canvas);
				img.setImageBitmap(mutableBitmap);
			}
		}
		
		private void init(){
			// Creating JSON Parser instance
			JSONParser jParser = new JSONParser();
			// getting JSON string from URL
			JSONObject json = jParser.getJSONFromUrl(url);
			if (json != null) {
				page = new Page();
				try {

					String url1 = (String) json.get(Constants.TAG_IMAGE_URL);
					page.setUrl(url1);
					JSONObject paperObj = json.getJSONObject(Constants.TAG_PAPER);
					page.setPaperHeight((float) paperObj
							.getLong(Constants.TAG_PAPER_HIEGHT));
					page.setPaperWidth((float) paperObj
							.getLong(Constants.TAG_PAPER_WIDTH));
					JSONArray jArray = json.getJSONArray(Constants.TAG_TAG_VIEW);
					for (int i = 0; i < jArray.length(); i++) {
						JSONObject oneObject = jArray.getJSONObject(i);
						// Pulling items from the array
						JSONObject tagObj = oneObject.getJSONObject(Constants.TAG_TAG);
						Tag tag = null;
						if (tagObj != null) {
							tag = new Tag();
							tag.setId(tagObj.getInt(Constants.TAG_TAG_ID));
							tag.setArPageId(tagObj.getInt(Constants.TAG_TAG_PAGE_ID));
							tag.setHeight((float) tagObj
									.getLong(Constants.TAG_TAG_HEIGHT));
							tag.setWidth((float) tagObj.getLong(Constants.TAG_TAG_WIDTH));
							tag.setStartX((float) tagObj
									.getDouble(Constants.TAG_TAG_STARTX));
							tag.setStartY((float) tagObj
									.getDouble(Constants.TAG_TAG_STARTY));
						}
						JSONArray jContent = oneObject
								.getJSONArray(Constants.TAG_CONTENT);
						if (jContent != null && jContent.length() != 0) {
							for (int j = 0; j < jContent.length(); j++) {
								JSONObject contentObject = jContent
										.getJSONObject(j);

								Content content = new Content();
								content.setTitle(contentObject
										.getString(Constants.TAG_CONTENT_TITLE));
								content.setUrl(contentObject
										.getString(Constants.TAG_CONTENT_URL));
								content.setType(contentObject
										.getString(Constants.TAG_CONTENT_TYPE));
								content.setDescription(contentObject
										.getString(Constants.TAG_CONTENT_DESC));
								if (tag != null)
									tag.getContentList().add(content);
							}
						}
						page.getTagsList().add(tag);
					}

					URL newurl = new URL(url1);
					mIcon_val = BitmapFactory.decodeStream(newurl
							.openConnection().getInputStream());
					img.setPaperHeight(mIcon_val.getHeight());
					page.setHeight(mIcon_val.getHeight());
					page.setWidth(mIcon_val.getWidth());
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {
		if(id == 1){
			Builder dialog = new AlertDialog.Builder(PaperaziActivity.this);
			dialog.setTitle("Error!");
			dialog.setMessage("Error connecting to the URL. Please try again later");
			dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					finish();
					
				}
			});
			return dialog.create();
		}
		else if(id == 2){
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle("Connection Failure");
			builder.setMessage("No Netowork Connection found!");
			builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					finish();
				}
			});
			return builder.create();
		}
		else if(id == 3){
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle("Capture Failure");
			builder.setMessage("Error in capturing the QR code! Please try again");
			builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					Intent intent = new Intent(getApplicationContext(), MainActivity.class);
					startActivity(intent);
					finish();
				}
			});
			return builder.create();
		}
		return super.onCreateDialog(id);
	}
}
